//
// Created by mmuee on 2024/4/23.
//

#include "ByteBuffer.hpp"

ByteBuffer::ByteBuffer()
{
    resize(0);
}

ByteBuffer::ByteBuffer(uint64_t size)
{
    resize(size);
}

ByteBuffer::ByteBuffer(ByteBuffer const &buffer)
{
    *this = buffer;
}

ByteBuffer::ByteBuffer(uint64_t size, void* data, bool unmanaged)
    : _size(size), _data((uint8_t*)data), _unmanaged(unmanaged)
{}

ByteBuffer& ByteBuffer::operator=(const ByteBuffer& other)
{
    this->_size = other._size;
    this->_unmanaged = other._unmanaged;
    if (this->_unmanaged)
    {
        this->_data = other._data;
    }
    else
    {
        this->_data = new uint8_t[this->_size]();
        memcpy(this->_data, other._data, this->_size);
    }
    return *this;
}

ByteBuffer& ByteBuffer::operator=(ByteBuffer&& other) noexcept
{
    this->_data = other._data;
    this->_size = other._size;
    this->_unmanaged = other._unmanaged;

    other.clean();
    return *this;
}

void ByteBuffer::resize(uint64_t newSize)
{
    if (_unmanaged)
    {
        LOG_WARN("can not resize, buffer unmanaged reason.");
        return;
    }

    if (newSize == 0)
    {
        clean();
    }
    else if (newSize > _capacity)
    {
        auto oldData = _data;
        auto oldSize = _size;
        this->_data = new uint8_t[newSize]();

        memcpy(this->_data, oldData, oldSize);
        delete[] oldData;

        _capacity = newSize;
        _size = newSize;
    }
    else if (newSize > _size)
    {
        // 已申请的空间足够延展, 延展的空间清空下
        auto flexSpace = newSize - _size;
        auto flexData = this->_data + _size;
        memset(flexData, 0, flexSpace);
        _size = newSize;
    }
    else
    {
        _size = newSize;
    }
}

void ByteBuffer::clean()
{
    if (!_unmanaged)
        delete _data;
    _data = nullptr;
    _size = 0;
}